home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / alv.sun / alv.lha / src / dynamem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-08  |  4.3 KB  |  114 lines

  1. #include <stdio.h>
  2. #include <varargs.h>
  3.  
  4. /*
  5.  * dynamem(p, s, d,  dn, dn ....) allocates a d dimensional array, whose 
  6.  * dimensions are stored in a list starting at d1. Each array element is 
  7.  * of size s. p is a pointer with d levels of indirection to the memory area 
  8.  */
  9.  
  10. har *malloc();
  11.  
  12. har *
  13. ynamem(va_alist)
  14. a_dcl
  15. {
  16.         va_list ap;                /* varargs list traverser */
  17.         int max,                /* size of array to be declared */
  18.         *q;                     /* pointer to dimension list */
  19.         char **r,               /* pointer to begining of the array of the
  20.                                  * pointers for a dimension */
  21.         **s1, *t, *tree;        /* base pointer to begining of first array */
  22.         int i,                  /* loop counters */
  23.          j;
  24.         char **p;                /* pointer to memory area with d levels of indirection */
  25.         int s,                    /* individual array element size */
  26.         d;                        /* number of dimensions */
  27.         int *d1;                /* dimension list */
  28.  
  29.         va_start(ap);
  30.         p = va_arg(ap, char**);
  31.         s = va_arg(ap,int);
  32.         d = va_arg(ap,int);
  33.         if ((d1 = (int *) malloc (sizeof(int) * d)) == NULL)
  34.             error("malloc returned NULL");
  35.  
  36.         for(i=0;i<d;i++)
  37.             d1[i] = va_arg(ap,int);
  38.  
  39.         r = &tree;
  40.         q = d1;                /* first dimension */
  41.         max = 1;
  42.         for (i = 0; i < d - 1; i++, q++) {      /* for each of the dimensions
  43.                                                  * but the last */
  44.                 max *= (*q);
  45.                 if ((r[0] = (char *) malloc((unsigned) max * sizeof (char **))) == NULL) {
  46.                         free(d1);
  47.                         freeup(tree,i);
  48.                         return 0;
  49.                 }
  50.                 r = (char **) r[0];     /* step through to begining of next
  51.                                          * dimension array */
  52.         }
  53.         max *= s * (*q);        /* grab actual array memory */
  54.         if ((r[0] = (char *) malloc((unsigned) max)) == NULL) {
  55.                 free(d1);
  56.                 freeup(tree,d);
  57.                 return 0;
  58.         }
  59.  
  60.         /*
  61.          * r is now set to point to the begining of each array so that we can
  62.          * use it to scan down each array rather than having to go across and
  63.          * then down 
  64.          */
  65.         r = (char **) tree;     /* back to the begining of list of arrays */
  66.         q = d1;                 /* back to the first dimension */
  67.         max = 1;
  68.         for (i = 0; i < d - 2; i++, q++) {      /* we deal with the last
  69.                                                  * array of pointers later on */
  70.                 max *= (*q);    /* number of elements in this dimension */
  71.                 for (j = 1, s1 = r + 1, t = r[0]; j < max; j++) /* scans down array for
  72.                                                                  * first and subsequent
  73.                                                                  * elements */
  74.  
  75.                         /*
  76.                          *  modify each of the pointers so that it points to
  77.                          * the correct position (sub-array) of the next
  78.                          * dimension array. s1 is the current position in the
  79.                          * current array. t is the current position in the
  80.                          * next array. t is incremented before s is, but it
  81.                          * starts off one behind. *(q+1) is the dimension of
  82.                          * the next array. 
  83.                          */
  84.                         *s1++ = (t += sizeof (char **) * *(q + 1));
  85.                 r = (char **) r[0];     /* step through to begining of next
  86.                                          * dimension array */
  87.         }
  88.         max *= (*q);            /* max is total number of elements in the
  89.                                  * last pointer array */
  90.         for (j = 1, s1 = r + 1, t = r[0]; j < max; j++) /* same as previous
  91.                                                          * loop, but different
  92.                                                          * size factor */
  93.                 *s1++ = (t += s * *(q + 1));
  94.         va_end(ap);
  95.         free(d1);
  96.         return tree;            /* return base pointer */
  97. }
  98.  
  99. /*
  100.  * freeup releases all memory that we have already declared analogous to
  101.  * free() when using malloc() 
  102.  */
  103. reeup(r,d)
  104. har **r;
  105. nt d;
  106. {
  107.         char **p;
  108.         int i;
  109.  
  110.         for (p = r, i = 0; i < d; p = (char **) *p,i++)
  111.         if (p != NULL)
  112.             free(p);
  113. }
  114.